<?php

    /**
     * Abstract
     *
     * @package      Core
     * @subpackage   Controller_Response
     *
     * @license      GNU Lesser General Public Licence see LICENCE-LGPL file or http://www.gnu.org/licenses/lgpl.html
     */
    abstract class Core_Controller_Response_Abstract extends Core_Object
    {

	////////////////////////////////////////////////////////////////////////////
	//                                Variables                               //
	////////////////////////////////////////////////////////////////////////////

        /**
        * Type of the response
        *
        * @var string
        */
        protected $_type = null;

		/**
		 * Array of error messages
		 *
		 * @var array
		 */
        protected $_errorMessages = array();

		/**
		 * Flag indicating wether the response can embed more than one error message
		 *
		 * @var boolean
		 */
        protected $_acceptSeveralErrors = true;

		/**
		 * Array of HTTP header
		 *
		 * @var array
		 */
        protected $_httpHeaders = array();

		/**
		 * Flag indicating wether the header has been sent
		 *
		 * @var boolean
		 */
        protected $_httpHeadersSent = false;

		/**
		 * The HTTP header status message
		 *
		 * @var string
		 */
        protected $_httpStatusMsg = 'OK';

		/**
		 * The HTTP header status code
		 *
		 * @var string
		 */
		protected $_httpStatusCode = '200';

		/**
		 * Zend_Registry object
		 *
		 * @var Zend_Registry
		 */
		protected $_registry = null;

		/**
		 * Core_Controller_Coordinator object
		 *
		 * @var Core_Controller_Coordinator
		 */
		protected $_coordinator = null;

	////////////////////////////////////////////////////////////////////////////
	//                                 Methods                                //
	////////////////////////////////////////////////////////////////////////////

        /**
        * Constructor
        */
        public function __construct()
        {
            $this->_registry    = Zend_Registry::getInstance();
            $this->_coordinator	= Core_Controller_Coordinator::getInstance();
        }

        /**
         * Destructor
         */
        public function __destruct()
        {
            unset($this);
        }

        /**
         * Returns the response type
         *
         * @return      string      the name
         */
        public final function getType()
        {
            return $this->_type;
        }

        /**
         * Indicates wether the response can embed more than one error message
         *
         * @return      boolean     true if many
         */
        public final function acceptSeveralErrors()
        {
            return $this->_acceptSeveralErrors;
        }

        /**
         * Indicates wether there are errors
         *
         * @return      boolean
         */
        public final function hasErrors()
        {
            return count($this->_coordinator->getErrorMessages()) > 0;
        }

        /**
         * Adds an HTTP header to the response.
         * Will be sent during the output of the response
         *
         * @param       string      $htype : the header type ("Content-Type", "Date-modified"...)
         * @param       string      $hcontent : value of the header type
         * @param       boolean     $overwrite : false if the value should be set only if it doesn't still exist
         * @return      void
         */
        public function addHttpHeader($htype, $hcontent, $overwrite = true)
        {
            if (!$overwrite && isset($this->_httpHeaders[$htype])) {
                return;
            }

            $this->_httpHeaders[$htype] = $hcontent;
        }

        /**
         * Deletes all HTTP headers
         *
         * @return      void
         */
        public function clearHttpHeaders()
        {
            $this->_httpHeaders     = array();
            $this->_httpStatusCode  = '200';
            $this->_httpStatusMsg   = 'OK';
        }

        /**
         * Sets the HTTP status code for the HTTP header
         *
         * @param       string      $code : the status code (200, 404...)
         * @param       string      $msg : the message following the status code ("OK", "Not Found"..)
         * @return      void
         */
        public function setHttpStatus($code, $msg)
        {
            $this->_httpStatusCode  = $code;
            $this->_httpStatusMsg   = $msg;
        }

	////////////////////////////////////////////////////////////////////////////
	//                            Abstract Methods                            //
	////////////////////////////////////////////////////////////////////////////

        /**
         * Sends the response in the correct format.
         *
         * @return      boolean     true if the output is ok
         * @internal    should take care about errors
         */
        abstract public function output();

        /**
         * Sends a response with only error messages which appears during the action
         * (errors, warning, notice, exceptions...).
         * Type and error details depend on the application configuration
         */
        abstract public function outputErrors();

	////////////////////////////////////////////////////////////////////////////
	//                            Protected methods                           //
	////////////////////////////////////////////////////////////////////////////

        /**
         * Sends HTTP headers
         *
         * @return      void
         */
        protected function sendHttpHeaders()
        {
            header("HTTP/1.0 ". $this->_httpStatusCode .' '. $this->_httpStatusMsg);

            foreach ($this->_httpHeaders as $ht => $hc) {
                if (is_array($hc)) {
                    foreach ($hc as $hcvalue) {
                        header($ht .': '. $hcvalue);
                    }
                } else {
                    header($ht .': '. $hc);
                }
            }

            $this->_httpHeadersSent = true;
        }
    }
